#region Copyright (c) 2003-2004 ComponentGo!
/*
*********************************************************************
*                                                                   *
*       ComponentGo! Component Library                              *
*                                                                   *
*       Copyright (c) 2003-2004 ComponentGo!                        *
*       ALL RIGHTS RESERVED                                         *
*                                                                   *
*********************************************************************
*/
#endregion

using System;
using System.Collections;
using System.ComponentModel;

namespace ComponentGo.Calendars {

	/// <summary>
	/// A collection of resources managed by calendars grouping appointments.
	/// <seealso cref="RootCalendar.Resources"/>
	/// </summary>
	/// <remarks>
	/// Basic operations are adding one new resource
	/// <see cref="Add"/> or adding a group of resources <see cref="AddRange"/>.
	/// A <see cref="Remove"/> method is used to remove an resource from a calendar.<para/>
	/// Resources are read with a <see cref="P:Item(System.Int32)"/> indexer
	/// or with an enumerator.
	/// </remarks>
	[System.Runtime.InteropServices.ComVisible(true)]
	public class ResourceCollection : CollectionBase {

		#region General

		internal BaseCalendar calendar;

		#endregion

		#region IList

		/// <summary>
		/// Adds a new resource to a collection.
		/// </summary>
		/// <param name="resource">A newly added resource.</param>
		/// <returns>Index of a newly added resource in a collection.</returns>
		public int Add(Resource resource) {
			return List.Add(resource);
		}

		/// <summary>
		/// Adds a number of new resources to a collection.
		/// </summary>
		/// <param name="resources">A table of resources being added.</param>
		public void AddRange(Resource [] resources) {
			foreach (Resource resource in resources)
				resource.attach(this);
			InnerList.AddRange(resources);
			resync(true);
		}

		/// <summary>
		/// Checks whether an resource is already in the collection.
		/// </summary>
		/// <param name="resource">An resource object being checked.</param>
		/// <returns><c>true</c> means an object is already in a collection.</returns>
		public bool Contains(Resource resource) {
			return List.Contains(resource);
		}

		/// <summary>
		/// Returns an index of an object in a collection.
		/// </summary>
		/// <param name="resource">An resource object being checked.</param>
		/// <returns>If an object is found return an index of the object in a collection. 
		///		Returns -1 otherwise.</returns>
		public int IndexOf(Resource resource) {
			return List.IndexOf(resource);
		}

		/// <summary>
		/// Inserts an resource to a collection in a given place.
		/// </summary>
		/// <param name="index">Index, an object will have after it is inserted.</param>
		/// <param name="resource">An resource object being inserted.</param>
		public void Insert(int index, Resource resource) {
			List.Insert(index, resource);
		}

		/// <summary>
		/// Removes an resource object from a collection.
		/// </summary>
		/// <param name="resource">An resource object being removed.</param>
		public void Remove(Resource resource) {
			List.Remove(resource);
		}

		/// <summary>
		/// Indexer allowing for reading an resource from and writing an resource to a collection
		/// under a given index.
		/// </summary>
		/// <param name="index">An index of an resource in a collection.</param>
		/// <value>An resource being set.</value>
		public Resource this[int index] {
			get { return (Resource)List[index]; }
			set { List[index] = value; }
		}

		#endregion

		#region Overrides

		/// <summary>
		/// Implementation of <see cref="CollectionBase"/>.
		/// </summary>
		protected override void OnClear() {
			base.OnClear();
			foreach (Resource resource in List)
				resource.detach();
			resync(true);
		}

		/// <summary>
		/// Implementation of <see cref="CollectionBase"/>.
		/// </summary>
		protected override void OnInsert(int index, object value) {
			((Resource)value).attach(this);
			base.OnInsert(index, value);
			resync(true);
		}

		/// <summary>
		/// Implementation of <see cref="CollectionBase"/>.
		/// </summary>
		protected override void OnRemove(int index, object value) {
			base.OnRemove(index, value);
			((Resource)value).detach();
			resync(true);
		}

		/// <summary>
		/// Implementation of <see cref="CollectionBase"/>.
		/// </summary>
		protected override void OnSet(int index, object oldValue, object newValue) {
			base.OnSet(index, oldValue, newValue);
			((Resource)oldValue).detach();
			((Resource)newValue).attach(this);
			resync(true);
		}

		/// <summary>
		/// Implementation of <see cref="CollectionBase"/>.
		/// </summary>
		protected override void OnValidate(object value) {
			if (!(value is Resource))
				throw new ArgumentException("Incorrect class of object.");
		}

		internal void resync(bool reload) {
			if (calendar!=null)
				calendar.Resync(reload);
		}

		#endregion

	}

}
